package com.example;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import static org.springframework.http.HttpMethod.GET;

@SpringBootApplication
@Controller
public class OauthClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(OauthClientApplication.class, args);
    }

    private Logger logger = LoggerFactory.getLogger(OauthClientApplication.class);

    @Autowired
    RestTemplate restTemplate;

    //客户端id
    private String client_id = "datong";

    //安全key
    private String client_secret = "3f08da4a";

    //回调url
    private String redirect_uri = "http://localhost:8080/callback";

    private String base_url = "https://api.500px.me";

    //oauth server服务器的验证地址
    private String auth_server = base_url + "/oauth/authorize?client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&response_type=code";

    private String token_url = base_url + "/oauth/token";

    //获取用户信息url
    private String user_info_url = base_url + "/me";

    @RequestMapping(value = "login")
    public String login() {
        return "redirect:" + auth_server;
    }

    @RequestMapping(value = "/callback")
    @ResponseBody
    public Object callback(@RequestParam("code") String code) {

        //form 表单
        MultiValueMap parameters = new LinkedMultiValueMap();
        parameters.add("grant_type", "authorization_code");
        parameters.add("scope", "openid");
        parameters.add("client_secret", client_secret);
        parameters.add("client_id", client_id);
        parameters.add("code", code);
        parameters.add("redirect_uri", redirect_uri);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        //basic验证,base64加密,客户端id,安全key
        headers.add("Authorization", "Basic " + Base64Utils.encodeToString((client_id + ":" + client_secret).getBytes()));
        HttpEntity httpEntity = new HttpEntity(parameters, headers);
        JSONObject json = restTemplate.postForObject(token_url, httpEntity, JSONObject.class);
        logger.info("获取token:", json.toJSONString());

        //token
        String access_token = json.getString("access_token");


        headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + access_token);

        ResponseEntity<JSONObject> userInfo = restTemplate.exchange(user_info_url,
                GET,
                new HttpEntity(headers),
                JSONObject.class);

        logger.info("响应信息:" + userInfo);
        return userInfo.getBody();
    }


    @Bean
    public RestTemplate restTemplate() {
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

        //超时时间
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(3000)
                .setSocketTimeout(3000)
                .build();
        //最大并发数
        CloseableHttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(manager)
                .setMaxConnPerRoute(200)
                .setMaxConnTotal(200)
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        RestTemplate restTemplate = new RestTemplate(factory);
        restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());
        return restTemplate;
    }
}
